package lab.poc.erl;

import java.io.Serializable;

import static lab.poc.erl.Objects.equal;
import static lab.poc.erl.Objects.hash;
import static lab.poc.erl.Objects.hashCombine;

class Pair<T1, T2> implements Serializable {

	private static final long serialVersionUID = -5333836446698746427L;

	private final T1 item1;
	private final T2 item2;

	public Pair(final T1 first, final T2 second) {
		item1 = first;
		item2 = second;
	}

	public T1 fst() {
		return item1;
	}

	public T2 snd() {
		return item2;
	}

	public static <U1, U2> Pair<U1, U2> create(final U1 u1, final U2 u2) {
		return new Pair<U1, U2>(u1, u2);
	}

	@Override
	public boolean equals(final Object other) {
		if (this == other) {
			return true;
		}
		if (other instanceof Pair<?, ?>) {
			final Pair<?, ?> p = (Pair<?, ?>) other;
			if (equal(item1, p.item1) && equal(item2, p.item2)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public int hashCode() {
		final int hash = hashCombine(31, hash(item1));
		return hashCombine(hash, hash(item2));
	}

	@Override
	public String toString() {
		final StringBuilder buf = new StringBuilder("Pair: {");
		buf.append((item1 == null) ? "null" : item1.toString());
		buf.append(", ");
		buf.append((item2 == null) ? "null" : item2.toString());
		buf.append("}");
		return buf.toString();
	}
}
